<script setup>
import {ref, provide, reactive, inject, computed, onMounted, watch} from 'vue'
import LabelTable from "./label/LabelTable.vue";
import LabelFolderEditor from "./label_folder/LabelFolderEditor.vue";
import LabelAdd from "./label/label_editor/LabelAdd.vue";
import {useDialog,useMessage} from 'jiuqi-ui'
import {Split} from 'view-ui-plus'
import {getAllParentId, getTreeNodeById, scrollIntoView} from "../../utils/TreeHelper";
import IconEnum from "../../utils/iconEnum";
import DeleteConfirmDialog from "./components/DeleteConfirmDialog.vue";
import {Debounce} from "../../utils/debounce";
import DropdownSearch from "./components/DropdownSearch.vue";
//================================================【组件通信】============================================================
//发送请求组件
const context = inject('context')


//控制 标签分组处理对话框 显示与隐藏
const folderEditorDialogVisible = ref(false)
provide('folderEditorDialogVisible', folderEditorDialogVisible)

//向子组件传递 当前标签分组 和 子组件处理后需要触发的回调
//当前选中 标签分组
const curLabelFolder = reactive({
    id:'',
    pId:'',
    title:'',
    type:'',
    order:0,

    path:''
})
provide('labelFolder', {'folderInfo': curLabelFolder,
                        'editFolder': {removeCurrTreeNode},
                        'callback': {saveLabelFolderBack, saveLabelBack}})

//向子组件传递 维度项编辑器 显示与隐藏
const dimItemEditorVisiable = ref(false)
provide('dimItemEditorVisiable',dimItemEditorVisiable)

//向子组件传递 添加标签模态框  显示与隐藏
const labelAddVisible = ref(false)
provide('labelAddVisible', labelAddVisible)

//向子组件传递  删除确认对话框  显示与隐藏
const deleteConfirmDialogVisible = ref(false)
provide('deleteConfirmDialogVisible',deleteConfirmDialogVisible)
//================================================【公用相关】============================================================
//提示信息组件
const message = useMessage()
//对话组件
const dialog = useDialog()
//是否使用 标签分组对话框 进行添加分组
const addFolderFlag = ref(true)
//拖拽分隔符初始比例
const split = ref(0.15)
//子组件 LabelTable ref
const sonLabelTable = ref(null)
//当前树形选中节点
const currTreeNode = ref({})
//搜索内容
const searchKeyWord = ref('')
//保存标签  回调
function saveLabelBack() {

    //新增，编辑后刷新标签列表
    sonLabelTable.value.refreshTableData()
}
//刷新某一节点
function refreshOneNode(nodeId) {
  return new Promise((resolve)=>{
    context.getPlugin('http').get(`labelmanager/label/group/tree?pId=${nodeId}`).then((res) => {
      //加载最新数据
      const nodeDataArr = []
      for (let i = 0; i < res.data.length; i++) {
        const nodeData = res.data[i];
        if (!nodeData.isLeaf) {
          nodeData.loading = false
          nodeData.expand = false
        } else {
          nodeData.expand = true
        }
        nodeDataArr.push(nodeData)
      }
      let processNode = getTreeNodeById(treeData, nodeId)
      if (!processNode.children) processNode.children = reactive([])
      processNode.children.splice(0, processNode.children.length, ...nodeDataArr)
      processNode.expand = true
      processNode.selected = false
      resolve(processNode)
    })
  })
}

//新建标签分组、编辑标签分组  回调
function saveLabelFolderBack(folderInfo, path) {
    // 新建分组
    if (addFolderFlag.value) {
      refreshOneNode(currTreeNode.value.id).then(()=>{
        currTreeNode.value = getTreeNodeById(treeData,folderInfo.id)
        currTreeNode.value.selected = true
        scrollIntoView('treeScrollIntoViewTarget');
      })

    // 编辑回调
    } else {
        // 所属目录发生变化时
        if ((currTreeNode.value.pId == null && folderInfo.pId)
            ||
            (currTreeNode.value.pId !== null && currTreeNode.value.pId !== folderInfo.pId)) {

            //编辑后，所属目录是“基础数据”
            if (folderInfo.pId === 'JIUQI_BASEDATA_LABEL') {

                let movedFolderNode = cloneCurrTreeNode(currTreeNode.value)
                movedFolderNode.pId = 'JIUQI_BASEDATA_LABEL'

                // 旧父节点 删除 旧节点(编辑节点)
                removeCurrTreeNode()
                // 新父节点 添加 新节点(编辑节点)
                refreshOneNode('JIUQI_BASEDATA_LABEL').then(()=>{
                  // 更新 当前节点currTreeNode
                  currTreeNode.value = getTreeNodeById(treeData, movedFolderNode.id)
                  currTreeNode.value.selected = true
                  scrollIntoView('treeScrollIntoViewTarget');
                })
            } else {
                expandPath(path, 0)
            }

        //目录没有发生变化时
        }else {
          refreshOneNode(folderInfo.pId).then(()=>{
            // 更新 当前节点currTreeNode
            currTreeNode.value = getTreeNodeById(treeData, folderInfo.id)
            currTreeNode.value.selected = true
            scrollIntoView('treeScrollIntoViewTarget');
          })
        }
    }
}
//================================================【组件属性】============================================================
const addFolderDisabled = computed(() => !currTreeNode.value)
const modifyFolderDisabled = computed(() => !currTreeNode.value || currTreeNode.value.id === 'JIUQI_BASEDATA_LABEL')
const addLabelDisabled = computed(() => !currTreeNode.value )

// 监听当前选中节点，更新当前分组信息
watch(currTreeNode, () => {
    if (currTreeNode.value) {
        curLabelFolder.id = currTreeNode.value.id
        curLabelFolder.title = currTreeNode.value.title
        curLabelFolder.pId = currTreeNode.value.pId
        curLabelFolder.type = currTreeNode.value.type
    } else {
        curLabelFolder.id = ''
    }
}, {deep: true})
//触发搜索
watch(searchKeyWord, (newValue) => {
  Debounce(context.getPlugin('http').get('labelmanager/label/group/fuzzyMatch?keyWord=' + newValue).then((res) => {
    panelAllData.splice(0, panelAllData.length, ...res.data)
  }), 300)
})
//================================================【普通方法】============================================================
//==================================================================【搜索面板】
//面板全部数据
const panelAllData = reactive([])

//面板项点击
function searchPanelItemClick(clickItem) {
    //点击搜索表格 此时确认需要返回展示树形，展示树形原有高亮取消
    currTreeNode.value.id !== ''?
        getTreeNodeById(treeData,currTreeNode.value.id).selected = false
        :
        null

    //获取 标签分组溯源路径
    context.getPlugin('http').get(`labelmanager/label/group/getTracePath/${clickItem.type}/${clickItem.pId}`).then(({data}) => {
        //树形回显
        data.push(clickItem.id)
        expandPath(data,0)
    })
}
//==================================================================【页签分组树形相关】
//树形ref
const folderTree = ref(null)
//树形数据
const treeData = reactive([])

//获取标签分组树形根节点
function getTreeRootNode() {
    context.getPlugin('http').get("labelmanager/label/group/tree?pId=").then((res) => {
        treeData.splice(0,treeData.length,...res.data)

        //默认选中树形根节点
        let node = treeData[0]
        if (node === undefined)
            message.error('无根节点信息')
        else{
           refreshOneNode(node.id).then((refreshedNode)=>{
            currTreeNode.value = refreshedNode
             currTreeNode.value.selected = true
          })
        }
    });
}

//异步加载树形节点
function loadData(item, pathIndex, path) {
    return new Promise( (resolve) => {

          refreshOneNode(item.id).then((processNode)=>{
            //手动点击单个树形节点加载该节点直接下级树形数据
            resolve(processNode.children)

            //逐级加载模式
            if (pathIndex !== undefined)
              expandPath(path, ++pathIndex)
          })
    })
}

/**
 * 根据路径展开
 * @param {*} path          追溯路径
 * @param {*} pathIndex     准备处理的路径节点
 */
async function expandPath(path, pathIndex) {
        //不是 倒数第二个节点 则处理下一个路径节点
        if (pathIndex < path.length - 2) {
            const targetNode = getTreeNodeById(treeData, path[pathIndex])
            // 子节点存在
            if (targetNode.children) {
                targetNode.expand = true
                await expandPath(path, ++pathIndex)
            // 子节点不存在则加载子节点
            } else {
                loadData(targetNode, pathIndex, path)
            }

        //是倒数第二个节点
        } else if (pathIndex === path.length - 2) {
            //搜索框点击后逐级展开不删除原有旧数据
            //编辑操作回显需要删除原有旧数据
            if (addFolderFlag.value === false){
                // 旧父节点 删除 旧节点(编辑节点)
                removeCurrTreeNode()
                //后期不再使用，进行值初始化
                addFolderFlag.value = true
            }

            loadData(getTreeNodeById(treeData, path[pathIndex])).then(()=>{
              // 更新 当前节点currTreeNode
              currTreeNode.value = getTreeNodeById(treeData, path[pathIndex+1])
              currTreeNode.value.selected = true
              scrollIntoView('treeScrollIntoViewTarget');
            })
        }
}

//选择树形节点
function nodeSelected(node) {
  node.selected ? currTreeNode.value = node : currTreeNode.value = null;
}
//克隆树形节点
function cloneCurrTreeNode(currNodeData) {
    return {
        id: currNodeData.id,
        title: currNodeData.title,
        pId: currNodeData.pId,
        isLeaf: currNodeData.isLeaf,
        loading: currNodeData.loading,
        expand: currNodeData.expand,
        children: currNodeData.children,
        order:currNodeData.order
    }
}
//删除树形节点
function removeCurrTreeNode() {
        if (currTreeNode.value != null) {
            // 查父节点
            let targetNode = getTreeNodeById(treeData, currTreeNode.value.pId)
            if (targetNode) {
                const index = targetNode.children.findIndex((findItem)=>{
                    return findItem.id === currTreeNode.value.id
                })
                // 删除
                targetNode.children.splice(index, 1)

                //当删除后 父节点的子节点数组 为空，则将父节点设置成 叶子节点
                if (targetNode.children.length === 0) {
                    targetNode.children = null
                    targetNode.isLeaf = true
                }

                //当前节点置空
                currTreeNode.value = null

                //刷新表格
                saveLabelBack()
            }
        }
}
//==================================================================【页签分组操作相关】
//添加 页签分组
function addFolder() {
    //新增 标签分组 操作
    addFolderFlag.value = true
    //显示 标签分组处理对话框
    folderEditorDialogVisible.value = true
}

//编辑 页签分组
function modifyFolder() {
    //设置 当前标签分组  的 追溯路径
    curLabelFolder.path = getAllParentId(treeData,currTreeNode.value.pId)

    //编辑 标签分组 操作
    addFolderFlag.value = false
    //显示 标签分组处理对话框
    folderEditorDialogVisible.value = true
}

//删除 页签分组
function deleteFolder() {
    context.getPlugin('http').get(`labelmanager/label/group/checkDelete/${curLabelFolder.id}`)
        .then(({data}) => {
            if (!data){
                deleteConfirmDialogVisible.value = true
            } else{
                dialog.warning({
                    title: '提示',
                    content: '确认删除标签分组【' + curLabelFolder.title + '】？',
                    onOk: () => {
                        context.getPlugin('http').get(`labelmanager/label/group/delete/${currTreeNode.value.id}`)
                            .then(() => {
                                removeCurrTreeNode()
                                message.success('标签分组删除成功')
                            })
                    }
                })
            }
        })

}
//================================================【生命周期】============================================================
onMounted(() => {
    //获取标签分组树形根节点
    getTreeRootNode()
})
</script>

<template>
  <!--页面整体-->
    <div style="width: 100%;height: 100%">
        <j-layout class="layout">
            <!-- 页面顶部  [操作栏] -->
            <j-header class="toolbar">
                <j-space :size="10" style="align-items: center;height: 100%;">
                    <j-button :disabled="addFolderDisabled" @click="addFolder">新建分组</j-button>
                    <j-button :disabled="modifyFolderDisabled" @click="modifyFolder">编辑分组</j-button>
                    <j-button :disabled="modifyFolderDisabled" @click="deleteFolder">删除分组</j-button>
                    <j-button :disabled="addLabelDisabled" @click="labelAddVisible = true">新建标签</j-button>
                </j-space>
            </j-header>
            <!-- 页面主体内容 -->
            <j-content class="content-container">
                <Split v-model="split" :min="0.1" :max="0.7">
                    <!--标签分组 树形-->
                    <template #left>
                        <div class="left-content">
                            <div class="topSearch">
                                <DropdownSearch
                                    style="width: 100%"
                                    v-model:search-key-word="searchKeyWord"
                                    :panelAllData="panelAllData"
                                    @searchPanelItemClick="searchPanelItemClick">
                                  <template #dropDownItemTemp="{itemData}">
                                    {{itemData.title}}
                                  </template>
                                </DropdownSearch>
                            </div>
                            <j-tree
                                ref="folderTree"
                                v-model:data="treeData"
                                :load-data="loadData"
                                @select="nodeSelected"
                                select-type="check">
                                <template #node="{ title,selected }">
                                    <j-space :size="8">
                                        <span :class=" 'nvwa-iconfont' + IconEnum.notLeaf"></span>
                                        <span :class="selected ?' treeScrollIntoViewTarget' : ''">{{ title }}</span>
                                    </j-space>
                                </template>
                            </j-tree>
                        </div>
                    </template>
                    <!--标签 表格-->
                    <template #right>
                        <j-content class="right-content">
                            <LabelTable ref="sonLabelTable"></LabelTable>
                        </j-content>
                    </template>
                </Split>
            </j-content>
        </j-layout>
    </div>
  <!--标签分组 处理对话框-->
    <LabelFolderEditor v-if="folderEditorDialogVisible" :addFolderFlag="addFolderFlag"></LabelFolderEditor>
  <!--标签 添加页面-->
    <LabelAdd v-if="labelAddVisible" ></LabelAdd>
  <!--标签分组 删除页面-->
    <DeleteConfirmDialog v-if="deleteConfirmDialogVisible" :is-folder="true"></DeleteConfirmDialog>
</template>
<style scoped>
.layout {
    position: relative;
    overflow: hidden;
    min-width: 450px;
}

.toolbar {
    padding-left: 8px;
    position: relative;
    height: 49px !important;
    line-height: 49px;
    border-bottom: 1px solid #ccc;
}

.content-container {
    height: 100%;
}

.left-content {
    height: 100%;
    overflow: auto;
}
.topSearch {
    width: 100%;
    display: flex;
    flex-direction: row;
    margin-bottom: 0px;
}
.topSearch > :first-child > :first-child {
    display: block;
}
.right-content {
    height: 100%;
    overflow: auto;
    margin-left: 8px;
    padding: 10px 10px 20px 10px;
}
</style>
<!-- 临时方案：覆盖jiuqi-ui全局主题，后续jiuqi-ui功能完善后，会删除 -->
<style type="text/css">
.toolbar > div {
    height: 100%;
}

body {
    --jui-color-primary-1: #E4F0FF;
    --jui-color-primary-5: #56a1fc;
    --jui-color-primary-6: #2c8afb;
    --jui-color-primary-7: #2a83ee;
    --jui-common-zindex-1: 1000;
    --jui-common-zindex-2: 1000;
    --jui-color-font-1: #333;
}
</style>
